Skip to content

Conversation

@loafer-19
Copy link

@loafer-19 loafer-19 commented Jan 29, 2026

Pull Request

NautilusTrader prioritizes correctness and reliability, please follow existing patterns for validation and testing.

  • I have reviewed the CONTRIBUTING.md and followed the established practices

Summary

Add multiple enhancements to PolymarketExecutionClient:

  • Batch order submission via post_orders endpoint
  • Global cancel via cancel_all endpoint
  • Per-market cancel via cancel_market_orders endpoint
  • Post-only order support (with GTC/GTD time in force):About two weeks ago, post-only was not supported by the official packages.now supported.

Related Issues/PRs

N/A

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Improvement (non-breaking)
  • Breaking change (impacts existing behavior)
  • Documentation update
  • Maintenance / chore

Breaking change details (if applicable)

N/A

Documentation

  • Documentation changes follow the style guide (docs/developer_guide/docs.md)

Release notes

  • I added a concise entry to RELEASES.md that follows the existing conventions (when applicable)

Testing

Ensure new or changed logic is covered by tests.

  • Affected code paths are already covered by the test suite
  • I added/updated tests to cover new or changed logic

Added test cases in tests/integration_tests/adapters/polymarket/test_execution.py:

  • test_submit_order_list_success/partial_failure
  • test_cancel_all_global_success/partial_failure
  • test_cancel_market_orders_*
  • test_submit_order_post_only_gtc_success
  • test_submit_order_post_only_ioc_denied

Implement post_orders endpoint support for submitting multiple
orders in a single API call:

- Add PostOrdersArgs and SubmitOrderList imports
- Add _submit_order_list for batch order submission
- Add _validate_order_for_batch for order validation
- Add _sign_orders_for_batch to sign multiple orders
- Add _post_signed_orders_batch for batch submission with retry
- Add _reject_all_orders and _process_batch_response helpers
Add TestPolymarketBatchOrderSubmission test class with 6 test cases:
- test_submit_order_list_success
- test_submit_order_list_partial_failure
- test_submit_order_list_with_market_order_denied
- test_submit_order_list_empty_list
- test_submit_order_list_with_reduce_only_denied
- test_submit_order_list_with_post_only_denied
@CLAassistant
Copy link

CLAassistant commented Jan 29, 2026

CLA assistant check
All committers have signed the CLA.

- Add _cancel_all_global() using http_client.cancel_all()
- Add _cancel_market_orders() using http_client.cancel_market_orders()
- Enable post_only orders with GTC/GTD time in force
- Pass post_only parameter to post_order() and PostOrdersArgs
- Update tests for new post_only behavior (GTC/GTD required)
- Add tests for cancel_all_global and cancel_market_orders
@loafer-19 loafer-19 changed the title Add batch order submission (post_orders) to Polymarket adapter Add batch order submission (post_orders), cancel_all, cancel_market_orders, Post-only to Polymarket adapter Jan 29, 2026
@cjdsellers cjdsellers changed the title Add batch order submission (post_orders), cancel_all, cancel_market_orders, Post-only to Polymarket adapter Add Polymarket batch order support Jan 29, 2026
@cjdsellers
Copy link
Member

Hi @loafer-19

Thank you for the PR! I'll have capacity to review more closely next week.

In the mean time, here are some findings to potentially follow up on:

   Issues to Address                                                                                                                                    

  1. Index out of bounds risk (_process_batch_response:322-354)
  for i, result in enumerate(response):
      order = orders[i]
  1. If the API returns fewer results than orders submitted, this will raise IndexError. Should verify len(response) == len(orders) or use zip():
  for order, result in zip(orders, response, strict=True):
  2. Missing order state update for cancel methods (_cancel_all_global, _cancel_market_orders)

  2. These methods log cancellation results but don't update order state in the cache or generate cancel events. When orders are canceled via these
  endpoints, the local order state becomes stale. Consider:
    - Generating OrderCanceled events for successfully canceled orders
    - Or documenting that these are "fire and forget" methods requiring WebSocket updates
  3. Signing errors not handled (_sign_orders_for_batch)
  signed_order = await asyncio.to_thread(
      self._http_client.create_order,
      order_args,
      options=options,
  )
  3. If signing fails for one order, the entire batch fails with an unhandled exception. Consider wrapping in try/except and rejecting individual orders
  that fail to sign.
  4. expire_time_ns may be 0 (_sign_orders_for_batch:249)
  expiration=int(nanos_to_secs(order.expire_time_ns)),
  4. For GTC orders, expire_time_ns is typically 0. Verify that nanos_to_secs(0) = 0 is valid for the Polymarket API.

  📝 Minor Suggestions

  1. The _cancel_market_orders method has local imports that could be moved to module level for consistency:
  from nautilus_trader.adapters.polymarket.common.symbol import get_polymarket_condition_id
  from nautilus_trader.adapters.polymarket.common.symbol import get_polymarket_token_id
  1. These are already imported at the module level (lines 45-47).
  2. Consider adding a _reject_all_orders call if _sign_orders_for_batch raises an exception, to ensure orders don't get stuck in "submitted" state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants